package com.kxjlcc.testudp.udptool

import android.util.Log
import java.lang.Exception
import java.net.*
import java.nio.charset.Charset
import java.util.concurrent.Executors

class UDPTools {
    private val log = "udp_tool"
    private var datagramSocket: DatagramSocket
    private var listener: UDPConnectListener
    private val executor = Executors.newCachedThreadPool()

    constructor(listener: UDPConnectListener) {
        this.listener = listener
        datagramSocket = DatagramSocket()
        Log.d(log, "first constructor")
    }

    constructor(port: Int, listener: UDPConnectListener) {
        this.listener = listener
        datagramSocket = DatagramSocket(port)
        Log.d(log, "second constructor")
    }

    constructor(host: String, port: Int, listener: UDPConnectListener) {
        this.listener = listener
        val socketAddress = InetSocketAddress(host, port)
        datagramSocket = DatagramSocket(socketAddress)
        Log.d(log, "third constructor")
    }

    fun connect(remoteHost: String, remotePort: Int) {
        executor.submit {
            try {
                val remoteSocketAddress = InetSocketAddress(remoteHost, remotePort)
                datagramSocket.connect(remoteSocketAddress)
                listener.onConnect()

            } catch (e: Exception) {
                e.printStackTrace()
                listener.onError()
            }
        }
    }

    fun sendMsg(hostAddress: String, port: Int, byteArray: ByteArray): DatagramPacket {
        val dp = DatagramPacket(byteArray, byteArray.size, InetAddress.getByName(hostAddress), port)
        datagramSocket.send(dp)
        return dp
    }

    fun receiveMsg() {
        executor.submit {
            while (datagramSocket.isConnected) {
                val receiveDatagramPacket = DatagramPacket(ByteArray(1024), 0, 1024)
                datagramSocket.receive(receiveDatagramPacket)
                Log.d(log, "offset:${receiveDatagramPacket.offset} length:${receiveDatagramPacket.length}")
                val msg = String(
                    receiveDatagramPacket.data,
                    receiveDatagramPacket.offset,
                    receiveDatagramPacket.length,
//            编码方式和服务端编码方式保持一致，才不会出现乱码的情况
                    Charset.forName("GBK")
                )
                listener.onReceiveMsg(receiveDatagramPacket.socketAddress, msg)
            }
        }
    }

    fun close() {
        executor.submit {
            if (datagramSocket.isConnected) {
                datagramSocket.disconnect()
            }
            if (!datagramSocket.isClosed) {
                datagramSocket.close()
            }
            Log.d(log, "connect closed")
        }
    }
}